package com.star.warmwinter.http.config;

import android.net.ParseException;
import android.util.Log;

import com.google.gson.JsonParseException;

import org.json.JSONException;

import java.net.ConnectException;

import retrofit2.HttpException;

/**
 * Author: blackbai11
 * Date: 2017/10/20 16:18
 * Description:ExceptionHandle
 */
public class ExceptionHandle {

    //对应HTTP的状态码
    private static final int UNAUTHORIZED = 401;
    private static final int FORBIDDEN = 403;
    private static final int NOT_FOUND = 404;
    private static final int REQUEST_TIMEOUT = 408;
    private static final int INTERNAL_SERVER_ERROR = 500;
    private static final int BAD_GATEWAY = 502;
    private static final int SERVICE_UNAVAILABLE = 503;
    private static final int GATEWAY_TIMEOUT = 504;

    public static ApiException handleException(Throwable e) {
        ApiException ex;
        if (e instanceof HttpException) { //HTTP错误
            HttpException httpException = (HttpException) e;
            ex = new ApiException(e, ERROR.HTTP_ERROR);
            int code = httpException.code();
            Log.e("ExceptionHandle", "HTTP错误code:" + code);
            switch (code) {
                case UNAUTHORIZED:          //401 anauthorized 授权(当前请求需要用户验证)
                case FORBIDDEN:             //403 foribidden 禁止(服务器已经理解请求，但是拒绝执行它)
                case NOT_FOUND:             //404 not_found 找不到(服务器异常，请稍后再试)
                case REQUEST_TIMEOUT:       //408 request_timeout 请求超时
                case INTERNAL_SERVER_ERROR: //500 internal_server_error 内部服务错误(服务器遇到了一个未曾预料的状况，导致了它无法完成对请求的处理)
                case BAD_GATEWAY:           //502 bad_gateway 错误网关(作为网关或者代理工作的服务器尝试执行请求时，从上游服务器接收到无效的响应)
                case SERVICE_UNAVAILABLE:   //503 service_unavailable 服务不可达(由于临时的服务器维护或者过载，服务器当前无法处理请求)
                case GATEWAY_TIMEOUT:       //504 gateway_timeout 网关连接超时(作为网关或者代理工作的服务器尝试执行请求时，未能及时从上游服务器（URI标识出的服务器，例如HTTP、FTP、LDAP）或者辅助服务器（例如DNS）收到响应)
                default:
                    ex.message = "网络错误";  //其它均视为网络错误
                    break;
            }
        } else if (e instanceof ServerException) { //服务器返回的错误
            ServerException resultException = (ServerException) e;
            ex = new ApiException(resultException, resultException.code);
            ex.message = resultException.message;
            Log.e("ExceptionHandle", "服务器返回的错误code:" + resultException.code + ",msg:" + resultException.message);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            ex = new ApiException(e, ERROR.PARSE_ERROR);
            ex.message = "解析错误";            //均视为解析错误
        } else if (e instanceof ConnectException) {
            ex = new ApiException(e, ERROR.NETWORK_ERROR);
            ex.message = "连接失败";            //均视为网络错误
        } else if (e instanceof javax.net.ssl.SSLHandshakeException) {
            ex = new ApiException(e, ERROR.SSL_ERROR);
            ex.message = "证书验证失败";
            return ex;
        } else {
            ex = new ApiException(e, ERROR.UNKNOWN);
            ex.message = "未知错误";            //未知错误
        }
        return ex;
    }

    /**
     * 约定异常
     */
    public class ERROR {
        /**
         * 未知错误
         */
        static final int UNKNOWN = 1000;
        /**
         * 解析错误
         */
        static final int PARSE_ERROR = 1001;
        /**
         * 网络错误
         */
        public static final int NETWORK_ERROR = 1002;
        /**
         * 协议出错
         */
        public static final int HTTP_ERROR = 1003;
        /**
         * 证书出错
         */
        static final int SSL_ERROR = 1005;
    }

    public static class ApiException extends Exception {
        public int code;
        public String message;

        ApiException(Throwable throwable, int code) {
            super(throwable);
            this.code = code;
        }
    }

    /**
     * ServerException发生后，将自动转换为ApiException返回
     */
    private class ServerException extends RuntimeException {
        int code;
        String message;
    }

}
